home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / progut~1 / stdwin.zoo / alfa / stdwin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-18  |  7.9 KB  |  459 lines

  1. /* TERMCAP STDWIN -- BASIC ROUTINES. */
  2.  
  3. #ifdef unix
  4. #define DO_SIGNAL
  5. #define DO_SYSTEM
  6. #endif
  7.  
  8. #ifdef DO_SIGNAL
  9. #include <signal.h>
  10. #endif
  11.  
  12. #include "alfa.h"
  13.  
  14. int lines, columns;
  15.  
  16. static int handler(); /* Forward */
  17.  
  18. /* Initialization call.
  19.    Should be called only once, before any others.
  20.    Will exit when the initialization fails. */
  21.  
  22. void
  23. winit()
  24. {
  25.     winitnew((int*)NULL, (char***)NULL);
  26. }
  27.  
  28. /*ARGSUSED*/
  29. void
  30. winitnew(pargc, pargv)
  31.     int *pargc;
  32.     char ***pargv;
  33. {
  34.     int flags;
  35.     int err;
  36.     
  37. #ifdef DO_SIGNAL
  38.     (void) signal(SIGINT, handler);
  39. #ifdef NDEBUG
  40.     (void) signal(SIGQUIT, handler);
  41. #endif
  42.     (void) signal(SIGILL, handler);
  43.     (void) signal(SIGIOT, handler);
  44.     (void) signal(SIGEMT, handler);
  45.     (void) signal(SIGFPE, handler);
  46.     (void) signal(SIGBUS, handler);
  47.     (void) signal(SIGSEGV, handler);
  48.     (void) signal(SIGSYS, handler);
  49.     (void) signal(SIGTERM, handler);
  50. #endif /* DO_SIGNAL */
  51.     
  52.     getttykeydefs(0);    /* File descriptor 0 */
  53.     err= trmstart(&lines, &columns, &flags);
  54.     if (err != 0) {
  55.         fprintf(stderr, "STDWIN: trmstart error %d\n", err);
  56.         exit(2);
  57.     }
  58.     gettckeydefs();
  59.     if (lines > MAXLINES)
  60.         lines= MAXLINES;
  61.     trmputdata(0, lines-1, 0, "");
  62.     initsyswin();
  63.     _winitmenus();
  64. }
  65.  
  66. /* Termination call.
  67.    Should be called before the program exits
  68.    (else the terminal will be left in almost raw mode). */
  69.  
  70. void
  71. wdone()
  72. {
  73.     if (lines > 0) {
  74.         /* Move cursor to last screen line. */
  75.         trmputdata(lines-1, lines-1, 0, "");
  76.         trmsync(lines-1, 0);
  77.     }
  78.     lines= 0;
  79.     trmend();
  80. }
  81.  
  82. #ifdef DO_SIGNAL
  83.  
  84. /* Signal handler.
  85.    Print a message and exit. */
  86.  
  87. static
  88. handler(sig)
  89.     int sig;
  90. {
  91.     wdone();
  92.     signal(sig, SIG_DFL);
  93.     kill(0, sig);        /* Kill all others in our process group */
  94.     kill(getpid(), sig);    /* Commit suicide */
  95.     /* (On BSD, the signal is delivered to us only after we return.) */
  96. }
  97.  
  98. #endif /* DO_SIGNAL */
  99.  
  100. /* Essential data structures. */
  101.  
  102. WINDOW winlist[MAXWINDOWS] /* = {FALSE, ...}, ... */;
  103.  
  104. WINDOW *wasfront;    /* What the application thinks is active */
  105. WINDOW *front;        /* The window that is really active */
  106.     /* If these are not equal, an activate or deactivate event
  107.        will be generated by wevent before anything else. */
  108.  
  109. char uptodate[MAXLINES] /* = FALSE, ... */;
  110.  
  111. /* Open a window. */
  112.  
  113. WINDOW *
  114. wopen(title, drawproc)
  115.     char *title;
  116.     void (*drawproc)();
  117. {
  118.     int id;
  119.     WINDOW *win;
  120.     
  121.     for (win= &winlist[0]; win < &winlist[MAXWINDOWS]; ++win) {
  122.         if (!win->open)
  123.             break;
  124.     }
  125.     id= win - &winlist[0];
  126.     if (id >= MAXWINDOWS)
  127.         return NULL;    /* Too many windows open */
  128.     win->open= TRUE;
  129.     _wreshuffle();
  130.     win->tag= 0;
  131.     win->drawproc= drawproc;
  132.     win->title= strdup(title);
  133.     win->attr= wattr;
  134.     
  135.     win->offset= -win->top;
  136.     win->curh= win->curv= -1;
  137.     win->timer= 0;
  138.     
  139.     initmenubar(&win->mbar);
  140.     
  141.     front= win;
  142.     return win;
  143. }
  144.  
  145. /* Divide the available lines over the available windows.
  146.    Line 0 is for window 0, the system window, and is different:
  147.    it has no title, and is always one line high, except when it's
  148.    the only window. */
  149.  
  150. void
  151. _wreshuffle()
  152. {
  153.     int nwins= 0;
  154.     int nlines= lines;
  155.     int top= 0;
  156.     WINDOW *win;
  157.     
  158.     /* Count open windows. */
  159.     for (win= winlist; win < &winlist[MAXWINDOWS]; ++win) {
  160.         if (win->open)
  161.             ++nwins;
  162.     }
  163.     /* Assign each open window its share of the screen. */
  164.     for (win= winlist; win < &winlist[MAXWINDOWS]; ++win) {
  165.         if (win->open) {
  166.             int i= nlines/nwins;    /* This window's share */
  167.             int id= win - winlist;
  168.             /* Cause redraw event for old title position: */
  169.             if (win->top > 0)
  170.                 uptodate[win->top-1]= FALSE;
  171.             if (id == 0) {    /* System window */
  172.                 win->top= top;
  173.                 if (nwins > 1)
  174.                     i=1;
  175.             }
  176.             else
  177.                 win->top= top+1;
  178.             win->bottom= top + i;
  179.             nlines -= i;
  180.             --nwins;
  181.             for (i= top; i < win->bottom; ++i) {
  182.                 /* Should not cause a redraw of all lines! */
  183.                 uptodate[i]= FALSE;
  184.             }
  185.             top= win->bottom;
  186.             /* Cause redraw event for new title position: */
  187.             if (win->top > 0)
  188.                 uptodate[win->top-1]= FALSE;
  189.             /* Scroll back if negative line numbers visible: */
  190.             if (win->top + win->offset < 0)
  191.                 wshow(win, 0, 0,
  192.                     columns, win->bottom - win->top);
  193.             /* Show caret: */
  194.             if (win->curv >= 0)
  195.                 wshow(win, win->curh, win->curv,
  196.                     win->curh, win->curv);
  197.         }
  198.     }
  199. }
  200.  
  201. /* Close a window. */
  202.  
  203. void
  204. wclose(win)
  205.     WINDOW *win;
  206. {
  207.     int id= win - winlist;
  208.     
  209.     if (id < 0 || id >= MAXWINDOWS || !win->open)
  210.         return;
  211.     killmenubar(&win->mbar);
  212.     if (win == wasfront)
  213.         wasfront= NULL;
  214.     if (win == front)
  215.         front= NULL;
  216.     win->open= FALSE;
  217.     if (win->title != NULL) {
  218.         free(win->title);
  219.         win->title= NULL;
  220.     }
  221.     _wreshuffle();
  222.     /* Select another window. */
  223.     for (; win < &winlist[MAXWINDOWS]; ++win) {
  224.         if (win->open)
  225.             front= win;
  226.     }
  227.     if (front == NULL) {
  228.         for (win= winlist; win < &winlist[MAXWINDOWS]; ++win) {
  229.             if (win->open)
  230.                 front= win;
  231.         }
  232.     }
  233. }
  234.  
  235. /* Dummies for functions not supported by this version. */
  236.  
  237. /*ARGSUSED*/
  238. void
  239. wsetdefwinpos(h, v)
  240.     int h, v;
  241. {
  242. }
  243.  
  244. /*ARGSUSED*/
  245. void
  246. wsetdefwinsize(width, height)
  247.     int width, height;
  248. {
  249. }
  250.  
  251. /*ARGSUSED*/
  252. void
  253. wsetmaxwinsize(width, height)
  254.     int width, height;
  255. {
  256. }
  257.  
  258. /* Make a window the active window. */
  259.  
  260. void
  261. wsetactive(win)
  262.     WINDOW *win;
  263. {
  264.     int id= win - winlist;
  265.     
  266.     if (id < 0 || id >= MAXWINDOWS || !win->open)
  267.         return;
  268.     _wnewtitle(front);
  269.     front= win;
  270.     _wnewtitle(front);
  271. }
  272.  
  273. /* Select next, previous window.
  274.    Note: these will never select the system window. */
  275.  
  276. void
  277. _wselnext()
  278. {
  279.     WINDOW *win;
  280.     
  281.     for (win= front+1; win < &winlist[MAXWINDOWS]; ++win) {
  282.         if (win->open) {
  283.             wsetactive(win);
  284.             return;
  285.         }
  286.     }
  287.     for (win= winlist+1; win < front; ++win) {
  288.         if (win->open) {
  289.             wsetactive(win);
  290.             return;
  291.         }
  292.     }
  293. }
  294.  
  295. void
  296. _wselprev()
  297. {
  298.     WINDOW *win;
  299.     
  300.     for (win= front-1; win > winlist; --win) {
  301.         if (win->open) {
  302.             wsetactive(win);
  303.             return;
  304.         }
  305.     }
  306.     for (win= &winlist[MAXWINDOWS-1]; win > front; --win) {
  307.         if (win->open) {
  308.             wsetactive(win);
  309.             return;
  310.         }
  311.     }
  312. }
  313.  
  314. /* Force a redraw of the entire screen.
  315.    (This routine only sets 'invalid' bits for all lines;
  316.    the actual redraw is done later in wgetevent or wupdate.) */
  317.  
  318. void
  319. _wredraw()
  320. {
  321.     int i;
  322.     
  323.     for (i= 0; i < lines; ++i)
  324.         uptodate[i]= FALSE;
  325.     _wreshuffle();
  326.     trmundefined();
  327.     trmputdata(0, lines-1, 0, "");
  328. }
  329.  
  330. /* Temporarily restore cooked tty mode. */
  331.  
  332. _wcooked()
  333. {
  334.     trmputdata(lines-1, lines-1, 0, "");
  335.     trmsync(lines-1, 0);
  336.     trmend();
  337. }
  338.  
  339. /* Back to window mode.
  340.    If 'wait' flag is set, wait until a character is typed before
  341.    continuing. clearing the screen. */
  342.  
  343. _wstdwin(wait)
  344.     bool wait;
  345. {
  346.     int flags;
  347.     
  348.     if (wait) {
  349.         printf("\nCR to continue... ");
  350.         fflush(stdout);
  351.     }
  352.     (void) trmstart(&lines, &columns, &flags);
  353.     if (wait)
  354.         (void) trminput();
  355.     _wredraw();
  356.     wmessage((char *)NULL); /* Reset menu bar */
  357. }
  358.  
  359. /* Suspend the process (BSD Unix only). */
  360.  
  361. void
  362. _wsuspend()
  363. {
  364.     _wcooked();
  365.     trmsuspend();
  366.     _wstdwin(FALSE);
  367. }
  368.  
  369. /* Execute a shell command, if possible and necessary outside the window
  370.    manager.  If the 'wait' parameter is set, the window manager pauses
  371.    until a character is typed before continuing. */
  372.  
  373. int
  374. wsystem(cmd, wait)
  375.     char *cmd;
  376.     bool wait;
  377. {
  378. #ifdef DO_SYSTEM
  379.     int status;
  380.     _wcooked();
  381.     status= system(cmd);
  382.     _wstdwin(wait);
  383.     return status;
  384. #else
  385.     return -1;
  386. #endif
  387. }
  388.  
  389. /* Return active window. */
  390.  
  391. WINDOW *
  392. wgetactive()
  393. {
  394.     return front;
  395. }
  396.  
  397. /* Change a window's title. */
  398.  
  399. void
  400. wsettitle(win, title)
  401.     WINDOW *win;
  402.     char *title;
  403. {
  404.     if (win->title != NULL)
  405.         free(win->title);
  406.     win->title= strdup(title);
  407.     _wnewtitle(win);
  408. }
  409.  
  410. /* Set a window's extent (document size). Not implemented here. */
  411.  
  412. /*ARGSUSED*/
  413. void
  414. wsetdocsize(win, width, height)
  415.     WINDOW *win;
  416.     int width, height;
  417. {
  418. }
  419.  
  420. /* Get a window's window size. */
  421.  
  422. void
  423. wgetwinsize(win, pwidth, pheight)
  424.     WINDOW *win;
  425.     int *pwidth, *pheight;
  426. {
  427.     *pwidth= columns;
  428.     *pheight= win->bottom - win->top;
  429. }
  430.  
  431. /* Get the screen size in pixels. */
  432.  
  433. void
  434. wgetscrsize(ph, pv)
  435.     int *ph, *pv;
  436. {
  437.     *ph= columns;
  438.     *pv= lines;
  439. }
  440.  
  441. /* Get the screen size in mm.
  442.    Of course we don't know it; we pretend that the average character
  443.    is 3 mm wide and 6 mm high, which is a reasonable approximation
  444.    of reality on my terminal (an HP2621). */
  445.  
  446. void
  447. wgetscrmm(ph, pv)
  448.     int *ph, *pv;
  449. {
  450.     *ph= columns * 3;
  451.     *pv= lines * 6;
  452. }
  453.  
  454. void
  455. wfleep()
  456. {
  457.     trmbell();
  458. }
  459.